/*
 * This source code is part of TWaver 4.0
 *
 * Serva Software PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
 * Copyright 2002 - 2011 Serva Software. All rights reserved.
 */

package demo.editor.pipe.element;

import java.awt.Color;
import java.awt.Rectangle;
import java.beans.PropertyChangeEvent;
import java.util.Iterator;
import twaver.Element;
import twaver.Follower;
import twaver.Node;
import twaver.TWaverConst;
import twaver.TWaverUtil;
import demo.editor.pipe.Const;

public abstract class AbstractPipe extends Follower implements IPipe{
	private static Color FILL_COLOR = new Color(0xC0, 0xC0, 0xC0);
	private static Color OUTLINE_COLOR = new Color(0x00, 0xB2, 0x00);
	
	private int holeIndex = -1;
	private Color innerColor = OUTLINE_COLOR;
	private String innerStroke = TWaverConst.STROKE_SQUARE_THIN;
	
	public AbstractPipe(){
		super();
    	this.init();
	}
	
	public AbstractPipe(Object id){
		super(id);
    	this.init();
	}

    private void init() {
    	this.setSize(60, 60);
		this.putCustomDraw(true);
		this.putCustomDrawGradientColor(Color.white);
		this.putCustomDrawFillColor(FILL_COLOR);
		this.putCustomDrawOutline(true);
		this.putCustomDrawOutlineColor(OUTLINE_COLOR);
    }
    
	public int getHoleIndex() {
		return holeIndex;
	}

	public void setHoleIndex(int holeIndex) {
		int oldValue = this.holeIndex;
		this.holeIndex = holeIndex;
		this.firePropertyChange(Const.PROPERTYNAME_ABSTRACTPIPE_HOLEINDEX, oldValue, holeIndex);
		adjustBounds();
	}
    
	public Color getInnerColor() {
		return innerColor;
	}

	public void setInnerColor(Color innerColor) {
		Color oldValue = this.innerColor;
		this.innerColor = innerColor;
		this.firePropertyChange(Const.PROPERTYNAME_ABSTRACTPIPE_INNERCOLOR, oldValue, innerColor);
	}
    
	public String getInnerStroke() {
		return innerStroke;
	}

	public void setInnerStroke(String innerStroke) {
		String oldValue = this.innerStroke;
		this.innerStroke = innerStroke;
		this.firePropertyChange(Const.PROPERTYNAME_ABSTRACTPIPE_INNERSTROKE, oldValue, innerStroke);
	}
    
    public void adjustBounds(){ 
    	Node host = this.getHost();
    	if(host instanceof IPipe){
    		IPipe pipe = (IPipe)host;
			Rectangle bounds = pipe.getPipeHoleBoundsByHole(this);
			if(bounds != null){
				this.setLocation(bounds.x, bounds.y);
				this.setSize(bounds.width, bounds.height);
			}
    	}
    }
    
    protected void hostPropertyChange(PropertyChangeEvent evt){
    	super.hostPropertyChange(evt);
    	String propertyName = TWaverUtil.getPropertyName(evt);
		if(propertyName.equals(Const.PROPERTYNAME_SQUAREPIPE_DIRECTION) 
				|| propertyName.equals(TWaverConst.PROPERTYNAME_SIZE)
				|| propertyName.equals(Const.PROPERTYNAME_ROUNDPIPE_HOLECOUNT)
				|| propertyName.equals(Const.PROPERTYNAME_ROUNDPIPE_CENTERHOLE)
				|| propertyName.equals(Const.PROPERTYNAME_SQUAREPIPE_CELLCOUNTS)){
			adjustBounds();
		}
    }
    
    protected void adjustPosition(){
    	super.adjustPosition();
    	this.adjustBounds();
    }
	
	public IPipe getPipeHoleByHoleIndex(int holeIndex) {
		Iterator it = this.getChildren().iterator();
		while(it.hasNext()){
			Element child = (Element)it.next();
			if(child instanceof IPipe){
				IPipe hole = (IPipe)child;
				if(hole.getHoleIndex() == holeIndex){
					return hole;
				}
			}
		}
		return null;
	}
	
	public abstract Rectangle getPipeHoleBoundsByHoleIndex(int holeIndex);

	public Rectangle getPipeHoleBoundsByHole(IPipe hole) {
		return this.getPipeHoleBoundsByHoleIndex(hole.getHoleIndex());
	}
}